package com.tang.thepath.service;


import com.tang.thepath.exception.ApiException;
import com.tang.thepath.exception.TokenExpiredException;
import com.tang.thepath.model.BaseResponse;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by Administrator on 2017/3/20.
 */

abstract class BaseService {

    protected static <T> Observable<T> toSubscribe(Observable<BaseResponse<T>> observable) {
        return observable.map(new HttpResultFunc<T>())
                .retryWhen(new TokenFunc<>())
                .onErrorResumeNext(new Func1<Throwable, Observable<? extends T>>() {
                    @Override
                    public Observable<? extends T> call(Throwable throwable) {
                        return Observable.error(ApiException.exception(throwable));
                    }
                })
                .compose(new ThreadTransformer<T>());

    }

    private static class TokenFunc<T> implements Func1<Observable<? extends Throwable>, Observable<?>> {

        @Override
        public Observable<?> call(Observable<? extends Throwable> observable) {

            return observable.flatMap(new Func1<Throwable, Observable<?>>() {
                @Override
                public Observable<?> call(Throwable throwable) {
                    if (throwable instanceof TokenExpiredException) {
//                        return AuthService.refreshToken().observeOn(Schedulers.io());
                    }
                    return Observable.error(throwable);
                }
            });
        }
    }

    private static class HttpResultFunc<T> implements Func1<BaseResponse<T>, T> {
        @Override
        public T call(BaseResponse<T> tBaseResponse) {
            if (!tBaseResponse.isSuccess()) {
                throw ApiException.exception(tBaseResponse.getErrorCode(), tBaseResponse.getMessage(), new Throwable("数据异常"));
            }
            return tBaseResponse.getData();
        }
    }

    private static class ThreadTransformer<T> implements Observable.Transformer<T, T> {
        @Override
        public Observable<T> call(Observable<T> tObservable) {
            return tObservable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());

        }
    }


}
